;int descomprimir_archivo(char *nombre_arch_entrada, char *nombre_arch_salida)

%include 'macros/oc2_header_t.mac' 
%include "macros/personalizada.mac"

global descomprimir_archivo

extern cargar_tabla_codigo_desde_buffer
extern descomprimir_buffer
extern fopen
extern fread
extern calloc
extern ftell
extern fseek
extern rewind
extern fclose
extern fwrite
extern free

%define ptr_tabla_codigo [ebp - 4]
%define ptr_nombre_arch_entrada [ebp + 8]
%define ptr_nombre_arch_salida [ebp + 12]

%define SEEK_END 2

section .data
	read: db 'r'
	write: db 'w'
	
section .text
	
descomprimir_archivo:
	push ebp
	mov ebp, esp
	sub esp, 4
	push esi
	push edi
	push ebx
	
	mov eax, ptr_nombre_arch_entrada
	
	push dword read
	push eax
	call fopen
	add esp,8
	cmp eax,0
	jne sigo
	jmp error
	
sigo:
	
	mov esi,eax ;esi apunta al archivo
	
	push dword SEEK_END 
	push dword 0
	push esi
	call fseek     ;posiciono el pibote dentro del archivo al final
	add esp,12
	
	push esi
	call ftell  ;tengo el tamaño del archivo en eax
	add esp,4
	
	mov ebx, eax ;ebx = longitud del archivo completo en BYTES (el de entrada)
				 ;esi = FILE * al archivo

	push esi
	call rewind   ;rebobino para poder usar el fread
	add esp,4

cargarAbuffer:
		
	push ebx
	push dword 1
	call calloc     ;reservo espacio en la memoria para cargar el archivo comprimido
	add esp,8
	cmp eax,0
	jne sin_error
	jmp error

sin_error:	
	mov edi,eax
	
	;size_t fread ( void * ptr, size_t size, size_t count, FILE * stream )
	push esi        ;esi = FILE * al archivo
	push ebx	; 1 jajaja
	push dword 1		;ebx = longitud del archivo(el de entrada)
	push edi		;edi = ptr al buffer
	call fread      ;ahora en eax = cantidad de bytes que leyo 
	add esp, 16		;edi = ptr al buffer, osea, ptr al header
	
	push esi
	call fclose
	add esp, 4
	
	;int cargar_tabla_codigo_desde_buffer(unsigned char *src_buf, unsigned int size, codigo_t **tabla_codigo)
		
	lea esi, ptr_tabla_codigo
	push esi ; esi = ptr a ptr_tabla_codigo
	push ebx ; ebx = longitud del archivo completo en BYTES (el de entrada)
	push edi
	call cargar_tabla_codigo_desde_buffer
	add esp,12
	cmp eax, 0
	jne NEAR error
	
	mov ebx, [edi + off_tam_original_h]
	
	push ebx 								;pusheo para que cree espacio en memoria del tamaño del archivo original
	push dword 1						    
	call calloc			
	add esp,8								;eax = ptr archivo descomprimido
	
	mov esi, eax							;esi = ptr archivo descomprimido (buffer)

	mov eax,[edi + off_long_codificacion_h]      ;paso el tamaño de la codificacion de bit a bytes NO HACE FALTA
	; shr eax,3
	
	mov ecx,[edi + off_offset_codificacion_h]
	lea ecx,[edi + ecx]
	
	mov edx, ptr_tabla_codigo
	
	push edx						  ;ptr tabla codigo
	push ebx                          ;tamaño del archivo original
	push esi						  ;ptr dst buf
	push eax						  ;long de la codificacion en bytes
	push ecx						  ;ptr_codificacion
	call descomprimir_buffer
	add esp,20
	cmp eax,error_code
	je NEAR error	
	
	push edi
	call free
	add esp, 4
	
	mov edi,ptr_nombre_arch_salida
	
	push dword write
	push edi
	call fopen  ;eax apunta al archivo
	add esp,8
	cmp eax,0
	je error
	mov edi, eax
	
	;size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
	push eax
	push dword 1
	push ebx
	push esi
	call fwrite
	add esp,16
	cmp eax,0
	je error
	
	push esi
	call free
	add esp,4
	cmp eax,0
	je error
	
	push edi
	call fclose
	add esp,4 
	cmp eax,0
	jne error
	
	; Liberamos la memoria de la tabla de codigos.
	mov edi, ptr_tabla_codigo
	push edi
	call free
	add esp,4
	
	
	mov eax, 1; La funcion termino con exito y retorna 1.
	
	jmp fin
	
error:
	 xor eax, eax ; La funcion fallo y retorna 0 como codigo de error.
	
fin:
	pop ebx
	pop edi
	pop esi
	add esp, 4
	pop ebp
	ret
   
